﻿using System;
using System.Collections.Generic;

using System.Text;
using ITAP.ShprossesBuilder.Modelling.Components;
using System.Windows.Forms;
using System.Drawing;
using ITAP.ShprossesBuilder.Modelling;
using ITAP.Core.Modelling;

namespace ITAP.ShprossesBuilder.Manipulation
{
    public class CommandSelectComponent : IModelComponentCommand
    {
        private MouseManagerEvent mouseEvent;

        public MouseManagerEvent MouseEvent
        {
            get { return mouseEvent; }
            set { mouseEvent = value; }
        }

        private Point mouseDownPoint;
        private List<Type> acceptedTypesToSelect;
        private List<IComponent> componentsForProcessing;
        private ModelControl modelControl;

        public CommandSelectComponent(ModelControl modelControl, Type[] acceptedTypesToSelect)
        {
            componentsForProcessing = new List<IComponent>();
            this.acceptedTypesToSelect = new List<Type>(acceptedTypesToSelect);            
            this.modelControl = modelControl;
        }

        #region IModelComponentCommand Members

        public List<ITAP.ShprossesBuilder.Modelling.Components.IComponent> ComponentsForProcessing
        {
            get { return componentsForProcessing; }
            set { componentsForProcessing = value; }
        }

        #endregion

        #region IModelControlCommand Members

        public ModelControl ModelControl
        {
            get
            {
                return modelControl;
            }
            set
            {
                modelControl = value;
            }
        }

        public System.Drawing.Point MouseDownPoint
        {
            get
            {
                return mouseDownPoint;
            }
            set
            {
                mouseDownPoint = value;
            }
        }

        public System.Drawing.Point MouseUpPoint
        {
            get
            {
                return mouseDownPoint;
            }
            set
            {
                mouseDownPoint = value;
            }
        }

        public System.Drawing.Point MouseMovePoint
        {
            get
            {
                return mouseDownPoint;
            }
            set
            {
                mouseDownPoint = value;
            }
        }

        public bool ExecuteImmediately
        {
            get
            {
                return false;
            }
            set
            {
            }
        }

        #endregion

        #region ICommand Members

        public void StartExecute()
        {
            ModelPoint modelPoint = modelControl.ScreenToModel(mouseDownPoint);
            List<IComponent> componentsToSelect = modelControl.ModelContainer.GetComponentsByPoint(modelPoint, 1);

            if (mouseEvent.Key != (Keys.ShiftKey | Keys.Shift))
            {
                this.modelControl.DeselectAll();
                //this.modelControl.ModelContainer.SelectedComponentsStack.Clear();
                //foreach (IComponent innerComponent in modelControl.ModelContainer.AllInnerComponents)
                //    if(acceptedTypesToSelect.Contains(innerComponent.GetType()))
                //        innerComponent.Selected = false;
            }

            foreach (Type type in this.acceptedTypesToSelect)
            {
                for (int i = componentsToSelect.Count - 1; i >= 0; i--)
                {
                    IComponent processComponent = componentsToSelect[i];
                    //                foreach (IComponent processComponent in componentsToSelect)
                    if (processComponent.GetType() == type)
                    {
                        processComponent.SelectByPoint(modelPoint);
                        if (processComponent.Selected && !modelControl.ModelContainer.SelectedComponentsStack.Contains(processComponent))
                            modelControl.ModelContainer.SelectedComponentsStack.Add(processComponent);
                        else
                            modelControl.ModelContainer.SelectedComponentsStack.Remove(processComponent);

                        return;
                    }
                }
                //processComponent.Selected = true;
            }
        }

        public void Execute()
        {
        }

        public void EndExecute()
        {
        }

        public bool CanUndo
        {
            get { return false; }
        }

        public bool Undo(ModelControl modelControl)
        {
            throw new NotImplementedException();
        }

        public bool Redo(ModelControl modelControl)
        {
            throw new NotImplementedException();
        }

        public string Name
        {
            get { throw new NotImplementedException(); }
        }

        #endregion

        #region ICloneable Members

        public object Clone()
        {
            CommandSelectComponent clone = new CommandSelectComponent(modelControl, acceptedTypesToSelect.ToArray());
            clone.MouseEvent = this.MouseEvent;
            clone.MouseDownPoint = this.MouseDownPoint;
            clone.MouseMovePoint = this.MouseMovePoint;
            clone.MouseUpPoint = this.MouseUpPoint;
            clone.ComponentsForProcessing = new List<IComponent>(this.ComponentsForProcessing);
            clone.ExecuteImmediately = this.ExecuteImmediately;
            return clone;
        }

        #endregion

        #region ICommand Members


        public bool IsNeedModelUpdate
        {
            get { return false; }
        }

        #endregion

        #region ICommand Members


        private bool enabled = true;
        public bool Enabled
        {
            get
            {
                return enabled;
            }
            set
            {
                enabled = value;
            }
        }
        #endregion

        #region ICommand Members


        public bool IsNeedVisitorsUpdate
        {
            get { return true; }
        }

        #endregion
    }
}
